
package com.meraklisina.latexeditor.xmltools;

import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Node;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.swing.*;

/**
 *
 * @author Eray
 */
public class XmlHelper
{
    private String XmlTagName, AttributeName;

    // <editor-fold defaultstate="collapsed" desc="Properties">

    /**
     * @return the XmlTagName
     */
    public String getXmlTagName() {
        return XmlTagName;
    }

    /**
     * @param XmlTagName the XmlTagName to set
     */
    public void setXmlTagName(String XmlTagName) {
        this.XmlTagName = XmlTagName;
    }

    /**
     * @return the AttributeName
     */
    public String getAttributeName() {
        return AttributeName;
    }

    /**
     * @param AttributeName the AttributeName to set
     */
    public void setAttributeName(String AttributeName) {
        this.AttributeName = AttributeName;
    }

    // </editor-fold>


    public XmlHelper(String XmlTagName, String AttributeName)
    {
        this.XmlTagName = XmlTagName;
        this.AttributeName = AttributeName;
    }

    /**
     * Gets the attribute value of the given Xml Node with the desired attribute's
     * name.
     *
     * @param XmlNode
     * @param AttributeName
     * @return String Attribute Value
     */
    public String GetAttributeValueByAttributeName(Node XmlNode, String AttributeName)
    {
        Element element = (Element)XmlNode;
        return element.getAttribute(AttributeName);
    }
    /**
     * Gets the element value of the given Xml Node with the desired attribute's
     * value.
     *
     * <p>
     * <b>Important Note:</b> This function uses this class' <i>XmlTagName</i>
     * and <i>AttributeName</i> properties.
     * </p>
     *
     * @param XmlNode
     * @param AttributeValue
     * @return String Element Value
     */
    public String GetElementValueByAttributeValue(Node XmlNode, String AttributeValue)
    {
        String Result = "";

        Element element = (Element)XmlNode;

        NodeList elements = element.getElementsByTagName(XmlTagName);

        for(int i = 0; i < elements.getLength(); i++)
        {
            Element TheElement = (Element)elements.item(i);

            if(TheElement.getAttribute(AttributeName).equals(AttributeValue))
            {
                if(TheElement.getChildNodes().item(0) != null)
                {
                    Result = TheElement.getChildNodes().item(0).getNodeValue();
                    break;
                }

            }
        }

        return Result;
    }
    /**
     * Gets the element value of the given Xml Node with the desired attribute's
     * value. Also, the TagName of the elements and the Attribute Name of those
     * elements are needed to be specifed.
     *
     * @param XmlNode
     * @param AttributeValue
     * @return String Element Value
     */
    public String GetElementValueByAttributeValue(Node XmlNode, String AttributeValue, String XmlTagName, String AttributeName)
    {
        String Result = "";

        Element element = (Element)XmlNode;

        NodeList elements = element.getElementsByTagName(XmlTagName);

        for(int i = 0; i < elements.getLength(); i++)
        {
            Element TheElement = (Element)elements.item(i);

            if(TheElement.getAttribute(AttributeName).equals(AttributeValue))
            {
                if(TheElement.getChildNodes().item(0) != null)
                {
                    Result = TheElement.getChildNodes().item(0).getNodeValue();
                    break;
                }

            }
        }

        return Result;
    }
    /**
     * Gets the node list of the specified Xml node.
     *
     * <p>
     * <b>Important Note:</b> This function uses this class' <i>XmlTagName</i> property.
     * </p>
     *
     * @param XmlNode
     * @return NodeList
     */
    public NodeList GetNodeListByAttributeValue(Node XmlNode)
    {
        Element element = (Element)XmlNode;

        NodeList elements = element.getElementsByTagName(XmlTagName);

        return elements;
    }
    /**
     * Gets the node list of the specified Xml node. Also, the TagName of the
     * elements is needed to be specifed.
     *
     * @param XmlNode
     * @return NodeList
     */
    public NodeList GetNodeListByAttributeValue(Node XmlNode, String XmlTagName)
    {
        Element element = (Element)XmlNode;

        NodeList elements = element.getElementsByTagName(XmlTagName);

        return elements;
    }
    /**
     * Gets the node list of a given Xml file by its relative or physical path
     * with the desired Xml node.
     *
     * @param FilePath
     * @param XmlNode  Tag name
     * @return NodeList
     */
    public NodeList GetNodeListFromXmlFile(String FilePath, String XmlNode)
    {
        NodeList Result = null;

        try
        {
            File file = new File(FilePath);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            doc.getDocumentElement().normalize();
            Result = doc.getElementsByTagName(XmlNode);
        }
        catch (Exception ex)
        {
            JOptionPane.showMessageDialog(null, "Cannot get nodes from XML file! Reason: " + ex.getMessage(), "Getting NodeList Error", JOptionPane.ERROR_MESSAGE);
        }

        return Result;
    }
    /**
     * Gets the node list of a given Xml file by its relative or physical path
     * with XPath.
     *
     * @param FilePath
     * @param XPath
     * @return NodeList
     */
    public NodeList GetNodeListFromXmlFileWithXPath(String FilePath, String XPath)
    {
        NodeList Result = null;

        try
        {
            XPathFactory factory = XPathFactory.newInstance();
            XPath xPath = factory.newXPath();

            Result = (NodeList) xPath.evaluate(XPath, new InputSource(new FileReader(FilePath)), XPathConstants.NODESET);
         }
        catch (Exception ex)
        {
            JOptionPane.showMessageDialog(null, "Cannot get nodes from XML file with XPath! Reason: " + ex.getMessage(), "Getting NodeList With XPath Error", JOptionPane.ERROR_MESSAGE);
        }
        return Result;
    }


}
